module("Skill", package.seeall)


Skill = class("Skill")

Skill.__index = Skill

local nilfunction = function() end

function create(param, hero)
	local skill = Skill.new()

	skill.param = param
	skill.hero = hero

	return skill
end

function Skill:use()
	self.finished = false
	self:selectTargets()
	local aimHero = self.targets[1]
	if (not aimHero) then
		return
	end

	if (aimHero:getPositionX() < self.hero:getPositionX()) then
		self.hero:turnTo("left")
	else
		self.hero:turnTo("right")
	end

    if (self.param.attackRange > 0) then
    	if (cc.pGetDistance(cc.p(aimHero:getPosition()), cc.p(self.hero:getPosition())) < self.param.attackRange) then
    		self:playSkill()
    	else
    		self.hero:walkingTo(aimHero)
    	end
    else
        self:playSkill()
        print("playSkill immediately")
    end
end

function Skill:getEffectValue()
	return self.param.effectValue
end

function Skill:isCrit()
	return math.random(1, 100) > 80
end

function Skill:selectTargets()
	self.targets = {}

    if ("all" ~= self.param.selectTarget) then
    	local target = self.hero.enemyCorps:getNearestHero(self.hero)
    
    	if (target) then
    		table.insert(self.targets, target)
    	end
    else
        self.hero.enemyCorps:fillAllAliveHeros(self.targets)
    end
end

function Skill:playSkill()
	local function animationEvent(armatureBack,movementType,movementID)
	    local id = movementID
	    if movementType == ccs.MovementEventType.complete then
	    	self.hero._armature:getAnimation():setMovementEventCallFunc(nilfunction)
	        self.hero._armature:getAnimation():playWithIndex(self.hero.param.actionMap.standby)
	        self.finished = true
	    end
	end

    local function onFrameEvent( bone,evt,originFrameIndex,currentFrameIndex)
    	if (#self.param.missiles > 0) then
    		local x = self.hero:getPositionX() + 80 * self.hero:getScaleX()
    		local y = self.hero:getPositionY() + 60 * self.hero:getScaleY()
			for k,v in ipairs(self.param.missiles) do
				local p = MissileTemplates.value[v]
				local obj = Missile.create(p, self)
				obj:setPosition(cc.p(x,y))
    			obj:action(self.targets[1])
			end
    	else
	        for k,target in ipairs(self.targets) do
	        	target:attacked(self, self:getEffectValue())
	        end
	    end
    end

    if (self.param.immediately) then
        print("self.param.immediately")
        if (#self.param.missiles > 0) then
            local x = self.hero:getPositionX()
            local y = self.hero:getPositionY() + 60 * self.hero:getScaleY()
            for k,v in ipairs(self.param.missiles) do
                local p = MissileTemplates.value[v]
                local obj = Missile.create(p, self)
                obj:setPosition(cc.p(x,y))
                obj:action(self.targets[1])
            end
        end
        return
    end

	self.hero._armature:getAnimation():playWithIndex(self.param.action)
	self.hero._armature:getAnimation():setMovementEventCallFunc(animationEvent)
	self.hero._armature:getAnimation():setFrameEventCallFunc(onFrameEvent)
end

function Skill:onPositionChange()
	local aimHero = self.targets[1]

    self:selectTargets()
    local newAimHero = self.targets[1]
    if (newAimHero) then
        if (aimHero ~= newAimHero) then
            if (aimHero:getPositionX() < self.hero:getPositionX()) then
                self.hero:turnTo("left")
            else
                self.hero:turnTo("right")
            end
        
            if (cc.pGetDistance(cc.p(newAimHero:getPosition()), cc.p(self.hero:getPosition())) < self.param.attackRange) then
                self:playSkill()
                return false
            else
                self.hero:walkingTo(newAimHero)
            end
            return true
        end
    end

	local p1 = cc.p(aimHero:getPosition())
	local p2 = cc.p(self.hero:getPosition())

	local d = cc.pGetDistance(p1, p2)
	if (cc.pGetDistance(cc.p(aimHero:getPosition()), cc.p(self.hero:getPosition())) < self.param.attackRange) then
	   self:playSkill()
        return false
	end

	return true
end

function Skill:isFinished()
	return self.finished
end